package cn.px.service.fill.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.px.common.util.*;
import com.github.pagehelper.PageHelper;
import cn.px.common.bean.AbstractPageResultBean;
import cn.px.common.cache.DictCache;
import cn.px.common.enums.DictTypeEnum;
import cn.px.common.model.UserInfo;
import cn.px.dao.bean.MyPage;
import cn.px.dao.bean.MyVOPage;
import cn.px.dao.dto.fill.FillProjectQuantityDTO;
import cn.px.dao.entity.fill.FillProjectQuantity;
import cn.px.dao.entity.upms.SysDept;
import cn.px.dao.enums.DeptNatureEnum;
import cn.px.dao.mapper.fill.FillProjectQuantityMapper;
import cn.px.dao.mapper.upms.SysDeptMapper;
import cn.px.dao.util.DataFieldUtil;
import cn.px.dao.util.UserUtil;
import cn.px.dao.vo.im.base.ImportResultVO;
import cn.px.dao.vo.im.fill.ImportFillProjectQuantityVO;
import cn.px.dao.vo.query.fill.FillProjectQuantityVO;
import cn.px.dao.vo.query.upms.SysDeptVO;
import cn.px.service.base.impl.BaseServiceImpl;
import cn.px.service.fill.FillProjectQuantityService;
import cn.px.service.util.ExecuteSql;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * @Description 填报项目工程量配置 service 实现类
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2020,北京乾元坤和科技有限公司 All rights reserved.
 */
@AllArgsConstructor
@Service("fillProjectQuantityService")
public class FillProjectQuantityServiceImpl extends BaseServiceImpl<FillProjectQuantityMapper, FillProjectQuantity, FillProjectQuantityDTO> implements FillProjectQuantityService {

    private final SysDeptMapper sysDeptMapper;

    @Override
    public int batchDelete(List<String> ids) {
        Weekend<FillProjectQuantity> weekend = new Weekend<>(FillProjectQuantity.class);
        WeekendCriteria<FillProjectQuantity, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andIn(FillProjectQuantity::getId, ids);
        FillProjectQuantity update = new FillProjectQuantity();
        update.setDelFlag(true);
        mapper.updateByExampleSelective(update, weekend);
        return 1;
    }

    @Override
    public void deleteByPrimaryKey(String id) {
        this.batchDelete(ListUtils.newArrayList(id));
    }

    @Override
    public FillProjectQuantityVO selectById(String id) {
        FillProjectQuantity fillProjectQuantity = mapper.selectByPrimaryKey(id);
        FillProjectQuantityVO vo = BeanConverterUtil.copyObjectProperties(fillProjectQuantity, new FillProjectQuantityVO());
        if (StringUtils.isNotBlank(fillProjectQuantity.getParentId())) {
            FillProjectQuantity parent = mapper.selectByPrimaryKey(fillProjectQuantity.getParentId());
            vo.setParentName(parent.getName());
        }
        return vo;
    }

    @Override
    public List<FillProjectQuantityVO> selectVoList(FillProjectQuantityDTO record) {
        return mapper.selectList(record);
    }

    @Override
    public List<FillProjectQuantity> getModelListByDTO(FillProjectQuantityDTO model) {
        Weekend<FillProjectQuantity> weekend = new Weekend<>(FillProjectQuantity.class);
        WeekendCriteria<FillProjectQuantity, Object> weekendCriteria = weekend.weekendCriteria();
        Integer filter = model.getFilter();
        if (filter != null && filter.equals(1)) {
            // 获取项目部的配置项
            UserInfo userInfo = SecurityUtils.getUserInfo();
            SysDeptVO dept = UserUtil.getUserNatureDept(DeptNatureEnum.XIANG_MU_BU, userInfo);
            weekendCriteria.andEqualTo(FillProjectQuantity::getDeptId, dept.getDeptId());
        }
        ExecuteSql.executeNotBlank(model.getKeyword(), () ->
                weekendCriteria.andLike(FillProjectQuantity::getName, model.getKeyword()));
        ExecuteSql.executeNotBlank(model.getDeptId(), () ->
                weekendCriteria.andEqualTo(FillProjectQuantity::getDeptId, model.getDeptId()));
        ExecuteSql.executeNotNull(model.getDelFlag(), () ->
                weekendCriteria.andEqualTo(FillProjectQuantity::getDelFlag, model.getDelFlag()));
        return mapper.selectByExample(weekend);
    }

    @Override
    public AbstractPageResultBean<FillProjectQuantity> selectPageInfo(FillProjectQuantityDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage<>(this.getModelListByDTO(record));
    }

    private void validModel(FillProjectQuantityDTO model) {
        String deptId = model.getDeptId();
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
        model.setDeptName(sysDept.getName());
    }

    @Override
    public FillProjectQuantity saveModelByDTO(FillProjectQuantityDTO model) {
        this.validModel(model);
        String parentId = model.getParentId();
        FillProjectQuantity parentProject = null;
        if (StringUtils.isNotBlank(parentId)) {
            parentProject = mapper.selectByPrimaryKey(parentId);
        }
        String parentCode = null;
        if (parentProject != null) {
            parentCode = parentProject.getCode();
        }
        String code = this.getCode(parentCode, parentId);
        model.setCode(code);
        return super.saveModelByDTO(model);
    }


    /**
     * 获得code
     *
     * @param parentCode :
     * @param parentId   :
     * @return :
     */
    private String getCode(String parentCode, String parentId) {
        Weekend<FillProjectQuantity> weekend = new Weekend<>(FillProjectQuantity.class);
        if (StringUtils.isNotBlank(parentCode)) {
            weekend.weekendCriteria().andEqualTo(FillProjectQuantity::getParentId, parentId);
        } else {
            weekend.weekendCriteria().andIsNull(FillProjectQuantity::getParentId);
            weekend.weekendCriteria().orEqualTo(FillProjectQuantity::getParentId, "");
            weekend.weekendCriteria().orEqualTo(FillProjectQuantity::getParentId, "0");
        }
        weekend.orderBy(DataFieldUtil.fnToFieldName(FillProjectQuantity::getCode)).desc();
        List<FillProjectQuantity> projectQuantities = mapper.selectByExample(weekend);

        if (CollectionUtils.isEmpty(projectQuantities)) {
            parentCode += "00001";
        } else {
            String maxProject = projectQuantities.get(0).getCode();
            String code = maxProject.substring(maxProject.length() - 5);
            code = String.format("%05d", Integer.parseInt(code) + 1);
            parentCode = maxProject.substring(0, maxProject.length() - 5) + code;
        }
        return parentCode;
    }

    @Override
    public void modModelByDTO(FillProjectQuantityDTO model) {
        this.validModel(model);
        super.modModelByDTO(model);
    }

    @Override
    public MyVOPage<FillProjectQuantityVO> selectPageList(FillProjectQuantityDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyVOPage<>(mapper.selectList(record));
    }

    @Override
    public void updateCloseProject(FillProjectQuantityDTO model) {
        FillProjectQuantity quantity = mapper.selectByPrimaryKey(model.getId());
        Weekend<FillProjectQuantity> weekend = new Weekend<>(FillProjectQuantity.class);
        WeekendCriteria<FillProjectQuantity, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andLike(FillProjectQuantity::getCode, quantity.getCode() + "%");
        mapper.updateByExampleSelective(new FillProjectQuantity().setCloseProject(model.getCloseProject()), weekend);
    }

    @Override
    public ImportResultVO importData(List<ImportFillProjectQuantityVO> modelList) {
        // 查询该项目部
        // 查询父级
        List<String> parentNameList = ListUtils.newArrayList();
        Map<String, String> map = MapUtils.newHashMap(parentNameList.size());
        // 处理数据
        ImportResultVO result = new ImportResultVO().setTotal(0).setMessage("").setErrorNum(0);
        StringBuilder sb = new StringBuilder();
        Map<String, Integer> unitMap = DictCache.getValueByLabelMapByType(DictTypeEnum.FILL_PROJECT_QUANTITY_UNIT.getType());
        String base = "序号为%s的%s数据在系统不存在；\n\t";
        for (ImportFillProjectQuantityVO item : modelList) {
            boolean error = false;
            // 校验不可为空字段
            String projectDeptName = item.getParentDeptName();
            String surah = item.getSurah();
            String parentName = item.getParentName();
            String name = item.getName();
            String unitStr = item.getUnitStr();
            String siteUnitStr = item.getSiteUnitStr();
            BigDecimal aggregate = item.getAggregate();
            BigDecimal price = item.getPrice();
            BigDecimal totalPrice = item.getTotalPrice();
            if (StringUtils.isBlank(projectDeptName) || StringUtils.isBlank(surah) || totalPrice == null
                    || StringUtils.isBlank(parentName) || StringUtils.isBlank(name) || price == null
                    || StringUtils.isBlank(unitStr) || StringUtils.isBlank(siteUnitStr) || aggregate == null) {
                sb.append(String.format("序号为%s的关键数据不能为空；\n\t", item.getIndex()));
                error = true;
            } else {
                parentName = item.getParentName().trim();
                // 处理单位
                Integer unit = unitMap.get(unitStr);
                Integer siteUnit = unitMap.get(siteUnitStr);
                if (unit == null) {
                    sb.append(String.format(base, item.getIndex(), "单位"));
                    error = true;
                }
                if (siteUnit == null) {
                    sb.append(String.format(base, item.getIndex(), "位置单位"));
                    error = true;
                }
                item.setUnit(unit);
                item.setSiteUnit(siteUnit);
                // 处理部门
                String deptName = item.getDeptName();
                String parentDeptName = item.getParentDeptName();


            }

            // 若是有问题则汇总
            if (error) {
                result.setErrorNum(result.getErrorNum() + 1);
                // 超哥10条则直接提示
                if (result.getErrorNum() > 10) {
                    result.setMessage(sb.toString());
                    return result;
                }
            } else {
                item.setParentName(parentName);
                map.put(parentName, parentName);
            }
        }
        // 检查校验是否有问题
        if (result.getErrorNum() > 0) {
            result.setMessage(sb.toString());
            return result;
        }

        map.forEach((key, val) -> parentNameList.add(key));

        // 查询所有父级工程
        Weekend<FillProjectQuantity> weekend = new Weekend<>(FillProjectQuantity.class);
        WeekendCriteria<FillProjectQuantity, Object> weekendCriteria = weekend.weekendCriteria();
        weekendCriteria.andIn(FillProjectQuantity::getName, parentNameList);
        List<FillProjectQuantity> projectQuantities = mapper.selectByExample(weekend);
        Map<String, FillProjectQuantity> parentMap = MapUtils.newHashMap(projectQuantities.size());
        projectQuantities.forEach(item -> {
            // 筛选未查到的父级工程
            map.remove(item.getName());
            parentMap.put(item.getName(), item);
        });
        // 判断是否有父级工程未筛选到,提示错误
        if (CollectionUtil.isNotEmpty(map)) {
            sb.append(String.format("父级工程%s系统粗存在", ListUtils.toString(ListUtils.getList(map.keySet().toArray()))));
            result.setErrorNum(1);
            result.setMessage(sb.toString());
            return result;
        }
        // 校验部门

        // 封装数据

        return null;
    }
}
